<template>
  <div class="chat-messages">
    <!-- 加载更多按钮 -->
    <div v-if="hasMore" class="load-more">
      <el-button :loading="loading" text @click="loadMore">加载更多</el-button>
    </div>

    <!-- 消息列表 -->
    <div class="messages-list" ref="messagesContainer">
      <div v-if="currentChatMessages.length === 0" class="no-messages">
        暂无消息
      </div>
      <template v-else>
        <div
          v-for="msg in currentChatMessages"
          :key="msg.msgKey"
          class="message-item"
          :class="{ 'message-mine': isMine(msg) }"
        >
          <div class="message-avatar">
            <el-avatar :size="36" :src="getAvatar(msg)" @error="() => true">
              {{ (getName(msg) || "").charAt(0) || "?" }}
            </el-avatar>
          </div>
          <div class="message-content">
            <div class="message-info">
              <span class="sender-name">{{ getName(msg) }}</span>
              <span class="message-time">{{
                msg.msg?.time ? formatTime(msg.msg.time) : ""
              }}</span>
            </div>
            <div class="message-text">
              <!-- 发送状态 -->
              <span v-if="isMine(msg)" class="message-status">
                <el-icon v-if="msg.status === 'sending'" class="sending"
                  ><Loading
                /></el-icon>
                <el-tooltip
                  v-if="msg.status === 'error'"
                  effect="dark"
                  :content="msg.errorMsg || '发送失败'"
                  placement="top"
                >
                  <el-icon class="error"><CircleCloseFilled /></el-icon>
                </el-tooltip>
              </span>
              <!-- 文本消息 -->
              <template v-if="msg.msg?.contentType === 1">
                <span
                  v-html="formatMessageContent(msg.msg?.content || '')"
                ></span>
              </template>
              <!-- 图片消息 -->
              <template v-else-if="msg.msg?.contentType === 2">
                <el-image
                  :src="getImageUrl(msg.msg?.content)"
                  :preview-src-list="[getImageUrl(msg.msg?.content)]"
                  fit="cover"
                  class="message-image"
                  :initial-index="0"
                >
                  <template #error>
                    <div class="image-error">
                      <el-icon><PictureFilled /></el-icon>
                      <span>图片加载失败</span>
                    </div>
                  </template>
                </el-image>
              </template>
            </div>
          </div>
        </div>
      </template>
    </div>

    <!-- 输入框区域 -->
    <div class="message-input">
      <!-- 工具栏 -->
      <div class="toolbar">
        <div class="tool-items">
          <el-popover
            placement="top"
            :width="420"
            trigger="click"
            popper-class="emoji-popover"
          >
            <template #reference>
              <el-button :icon="ChatRound" text>表情</el-button>
            </template>
            <div class="emoji-container">
              <div class="emoji-list">
                <span
                  v-for="emoji in emojis"
                  :key="emoji"
                  class="emoji-item"
                  @click="insertEmoji(emoji)"
                >
                  {{ emoji }}
                </span>
              </div>
            </div>
          </el-popover>
          <el-button :icon="PictureFilled" text @click="triggerUpload"
            >图片</el-button
          >
          <input
            ref="fileInput"
            type="file"
            accept="image/*"
            style="display: none"
            @change="handleFileChange"
          />
        </div>
      </div>

      <el-input
        v-model="inputMessage"
        type="textarea"
        :rows="3"
        placeholder="请输入消息"
        resize="none"
        @keyup.enter="sendMessage"
      />
      <div class="input-actions">
        <el-button type="primary" @click="sendMessage">发送</el-button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, watch, nextTick, computed } from "vue";
import {
  Loading,
  CircleCloseFilled,
  ChatRound,
  PictureFilled,
} from "@element-plus/icons-vue";
import socket from "@/utils/socket";
import { formatTime } from "@/utils/format";
import { ElMessage } from "element-plus";
import emojis from "@/utils/emoj";
import axios from "axios";
import { useMessageStore } from "@/stores/message";
import { storeToRefs } from "pinia";

const messageStore = useMessageStore();
const { currentChatMessages, currentChatImKey } = storeToRefs(messageStore);

const props = defineProps({
  chat: {
    type: Object,
    required: true,
  },
});

// 基础变量
const messagesContainer = ref(null);
const inputMessage = ref("");
const fileInput = ref(null);
const baseUrl = import.meta.env.VITE_API_BASE_URL || "";

// 分页相关
const page = ref(1);
const pageSize = ref(20);
const loading = ref(false);
const hasMore = ref(true);

// 加载更多历史消息
const loadMore = async () => {
  if (loading.value || !hasMore.value) return;

  loading.value = true;
  try {
    // 记录当前滚动位置
    const container = messagesContainer.value;
    const oldScrollHeight = container.scrollHeight;
    const oldScrollTop = container.scrollTop;

    page.value++;
    const response = await messageStore.getChatHistory(
      props.chat.imKey,
      page.value,
      pageSize.value
    );
    if (response && response.length < pageSize.value) {
      hasMore.value = false;
    }

    // 恢复滚动位置
    nextTick(() => {
      const newScrollHeight = container.scrollHeight;
      container.scrollTop = newScrollHeight - oldScrollHeight + oldScrollTop;
    });
  } catch (error) {
    console.error("加载更多消息失败:", error);
  } finally {
    loading.value = false;
  }
};

// 监听聊天对象变化
watch(
  () => props.chat,
  (newChat) => {
    if (newChat) {
      // 重置分页
      page.value = 1;
      hasMore.value = true;
      // 获取初始消息
      messageStore.getChatHistory(newChat.imKey, page.value, pageSize.value);
    }
  },
  { immediate: true }
);

// 获取消息历史
const fetchMessages = async (isLoadMore = false) => {
  if (loading.value) return;

  loading.value = true;
  try {
    const response = await messageStore.getChatHistory(
      props.chat.imKey,
      page.value,
      pageSize.value
    );
    const newMessages = response.reverse(); // 反转数组
    total.value = response.total;
    hasMore.value = currentChatMessages.value.length < total.value;

    if (isLoadMore) {
      // 加载更多时，新消息添加到列表开头
      currentChatMessages.value = [
        ...newMessages,
        ...currentChatMessages.value,
      ];
    } else {
      // 首次加载时直接赋值
      currentChatMessages.value = newMessages;
      // 滚动到底部，不使用平滑滚动
      await nextTick();
      scrollToBottom(false);
    }
  } catch (error) {
    ElMessage.error(error.message || "获取消息记录失败");
  } finally {
    loading.value = false;
  }
};

// 监听消息列表变化，只在新消息时滚动到底部
watch(
  currentChatMessages,
  (newMessages, oldMessages) => {
    if (!oldMessages || oldMessages.length === 0) {
      // 首次加载消息
      nextTick(() => {
        scrollToBottom(false);
      });
    } else if (
      newMessages.length > oldMessages.length &&
      newMessages[newMessages.length - 1].msg.time >
        oldMessages[oldMessages.length - 1].msg.time
    ) {
      // 只有在新消息添加到末尾时才滚动（发送新消息或收到新消息）
      nextTick(() => {
        scrollToBottom(true);
      });
    }
    // 获取所有未读消息
    const noReadMsg = newMessages.filter(
      (msg) => !msg.read && msg.msgKey && msg.user === currentChatImKey.value
    );
    if (noReadMsg.length > 0) {
      const msgKeys = noReadMsg.map((msg) => msg.msgKey);
      socket.emit(
        "setRead",
        {
          to: currentChatImKey.value,
          msgKeys: msgKeys,
        },
        (res) => {
          //console.log(res);
          messageStore.markMessagesAsRead(currentChatImKey.value);
        }
      );
    }
  },
  { deep: true }
);

// 生成消息ID
const generateMsgKey = () => {
  const timestamp = Date.now().toString();
  const random = Math.random().toString();
  return window.md5(timestamp + random);
};

// 发送消息
const sendMessage = () => {
  const content = inputMessage.value.trim();
  if (!content) return;

  console.log("开始发送消息...");

  // 生成消息ID
  const msgKey = generateMsgKey();
  console.log("生成的消息ID:", msgKey);

  // 构造发送的消息对象
  const message = {
    to: props.chat.imKey,
    content: content,
    contentType: 1, // 1文字消息
    msgKey: msgKey,
  };

  console.log("待发送的消息对象:", message);

  // 获取客服信息
  const imUserInfo = JSON.parse(localStorage.getItem("imUserInfo") || "{}");
  const baseUrl = import.meta.env.VITE_API_BASE_URL || "";

  // 构造本地消息对象并立即添加到列表
  const localMessage = {
    _id: msgKey,
    user: localStorage.getItem("imKey"),
    toUser: props.chat.imKey,
    msg: {
      from: localStorage.getItem("imKey"),
      fromName: imUserInfo.userName || "客服",
      fromAvatar: imUserInfo.avatar ? `${baseUrl}${imUserInfo.avatar}` : "",
      fromType: localStorage.getItem("userType"),
      to: props.chat.imKey,
      toName: props.chat.userName || "对方",
      toAvatar: props.chat.avatar || "",
      toType: props.chat.userType,
      content: content,
      contentType: 1,
      time: Date.now(),
      msgKey: msgKey,
    },
    read: false,
    msgKey: msgKey,
    createTime: new Date().toISOString(),
    status: "sending", // 发送中状态
  };

  console.log("本地消息对象:", localMessage);
  console.log("当前消息列表长度:", currentChatMessages.value.length);

  // 清空输入框
  inputMessage.value = "";

  // 添加到消息列表的末尾
  currentChatMessages.value = [...currentChatMessages.value, localMessage];
  console.log("添加消息后列表长度:", currentChatMessages.value.length);

  nextTick(() => {
    scrollToBottom(true); // 使用平滑滚动
  });

  // 发送消息
  socket.emit("chatMsg", message, (response) => {
    console.log("收到服务器响应:", response);

    // 找到对应的消息
    const msgIndex = currentChatMessages.value.findIndex(
      (msg) => msg.msgKey === msgKey
    );
    console.log("找到消息索引:", msgIndex);

    if (msgIndex === -1) return;

    if (response.code === 200) {
      console.log("发送成功，更新消息");
      // 更新消息状态为成功
      currentChatMessages.value[msgIndex].status = "success";
      // 更新消息内容
      currentChatMessages.value[msgIndex].msg = response.data;
    } else {
      console.log("发送失败:", response.message);
      // 更新消息状态为失败
      currentChatMessages.value[msgIndex].status = "error";
      currentChatMessages.value[msgIndex].errorMsg = response.message;
    }
  });
};

// 判断消息是否是自己发送的
const isMine = (message) => {
  const myImKey = localStorage.getItem("serviceImKey");
  return message.msg.from === myImKey;
};

// 获取头像
const getAvatar = (message) => {
  const myImKey = localStorage.getItem("serviceImKey");
  const baseUrl = import.meta.env.VITE_API_BASE_URL || "";
  const imUserInfo = JSON.parse(localStorage.getItem("imUserInfo") || "{}");

  if (message.msg.from === myImKey) {
    // 客服发送的消息，使用 imUserInfo 中的头像
    return imUserInfo.avatar ? `${baseUrl}${imUserInfo.avatar}` : "";
  } else {
    // 用户发送的消息，使用消息中的头像
    return message.msg.fromAvatar || "";
  }
};

// 获取名称
const getName = (message) => {
  const myImKey = localStorage.getItem("imKey");
  if (message.msg.from === myImKey) {
    // 我发送的消息
    return message.msg.fromName || "我";
  } else {
    // 对方发送的消息
    return message.msg.fromName || "对方";
  }
};

// 滚动到底部
const scrollToBottom = (smooth = true) => {
  if (messagesContainer.value) {
    const container = messagesContainer.value;
    const scrollHeight = container.scrollHeight;

    if (smooth) {
      container.scrollTo({
        top: scrollHeight,
        behavior: "smooth",
      });
    } else {
      container.scrollTop = scrollHeight;
    }
    console.log("滚动到底部", {
      scrollHeight,
      containerHeight: container.clientHeight,
      scrollTop: container.scrollTop,
    });
  }
};

// 插入表情
const insertEmoji = (emoji) => {
  inputMessage.value = (inputMessage.value || "") + emoji;
};

// 触发文件选择
const triggerUpload = () => {
  fileInput.value.click();
};

// 处理文件选择
const handleFileChange = async (event) => {
  const file = event.target.files[0];
  if (!file) return;

  // 检查文件类型
  if (!file.type.startsWith("image/")) {
    ElMessage.error("请选择图片文件");
    event.target.value = ""; // 清空选择
    return;
  }

  // 上传图片
  const formData = new FormData();
  formData.append("file", file);

  try {
    const response = await axios.post(
      `${baseUrl}/v1/user/uploadAvatar`,
      formData,
      {
        headers: {
          imtoken: `${localStorage.getItem("imtoken")}`,
        },
      }
    );

    if (response.data.code === 200) {
      // 发送图片消息
      const imageUrl = response.data.data;
      console.log("baseUrl", baseUrl);
      sendImageMessage(baseUrl + imageUrl);
    } else {
      ElMessage.error(response.data.message || "上传失败");
    }
  } catch (error) {
    console.error("上传失败:", error);
    ElMessage.error("上传失败，请重试");
  } finally {
    event.target.value = ""; // 清空选择，允许重新选择相同文件
  }
};

// 发送图片消息
const sendImageMessage = (imageUrl) => {
  console.log("imageUrl", imageUrl);
  // 生成消息ID
  const msgKey = generateMsgKey();

  // 构造发送的消息对象
  const message = {
    to: props.chat.imKey,
    content: imageUrl,
    contentType: 2, // 2图片消息
    msgKey: msgKey,
  };

  // 获取客服信息
  const imUserInfo = JSON.parse(localStorage.getItem("imUserInfo") || "{}");
  const baseUrl = import.meta.env.VITE_API_BASE_URL || "";

  // 构造本地消息对象
  const localMessage = {
    _id: msgKey,
    user: localStorage.getItem("imKey"),
    toUser: props.chat.imKey,
    msg: {
      from: localStorage.getItem("imKey"),
      fromName: imUserInfo.userName || "客服",
      fromAvatar: imUserInfo.avatar ? `${baseUrl}${imUserInfo.avatar}` : "",
      fromType: localStorage.getItem("userType"),
      to: props.chat.imKey,
      toName: props.chat.userName || "对方",
      toAvatar: props.chat.avatar || "",
      toType: props.chat.userType,
      content: imageUrl,
      contentType: 2,
      time: Date.now(),
      msgKey: msgKey,
    },
    read: false,
    msgKey: msgKey,
    createTime: new Date().toISOString(),
    status: "sending",
  };

  // 添加到消息列表
  currentChatMessages.value = [...currentChatMessages.value, localMessage];

  nextTick(() => {
    scrollToBottom(true);
  });

  // 发送消息
  socket.emit("chatMsg", message, (response) => {
    const msgIndex = currentChatMessages.value.findIndex(
      (msg) => msg.msgKey === msgKey
    );
    if (msgIndex === -1) return;

    if (response.code === 200) {
      currentChatMessages.value[msgIndex].status = "success";
      currentChatMessages.value[msgIndex].msg = response.data;
    } else {
      currentChatMessages.value[msgIndex].status = "error";
      currentChatMessages.value[msgIndex].errorMsg = response.message;
    }
  });
};

// 获取完整的图片URL
const getImageUrl = (path) => {
  if (!path) return "";
  const baseUrl = import.meta.env.VITE_API_BASE_URL || "";
  return path.startsWith("http") || path.startsWith("/api")
    ? path
    : `${baseUrl}${path}`;
};

// 格式化消息内容，识别并处理链接
const formatMessageContent = (content) => {
  if (!content) return "";

  // 匹配http/https链接
  const urlRegex = /(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/g;

  return content.replace(urlRegex, (url) => {
    return `<a href="${url}" target="_blank" class="message-link">${url}</a>`;
  });
};
</script>

<style scoped>
.chat-messages {
  height: 100%;
  display: flex;
  flex-direction: column;
  background-color: #f5f7fa;
}

.load-more {
  padding: 10px 0;
  text-align: center;
  background-color: #f5f7fa;
  border-bottom: 1px solid #e6e6e6;
}

.messages-list {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  display: flex;
  flex-direction: column;
}

.messages-list::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.messages-list::-webkit-scrollbar-thumb {
  border-radius: 3px;
  background-color: #c0c4cc;
}

.messages-list::-webkit-scrollbar-track {
  border-radius: 3px;
  background-color: #f5f7fa;
}

.message-item {
  display: flex;
  margin-bottom: 20px;
  align-items: flex-start;
}

.message-mine {
  flex-direction: row-reverse;
}

.message-avatar {
  margin: 0 10px;
}

.message-content {
  max-width: 60%;
}

.message-mine .message-content {
  align-items: flex-end;
}

.message-info {
  margin-bottom: 4px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.sender-name {
  font-size: 14px;
  color: #666;
}

.message-time {
  font-size: 12px;
  color: #999;
}

.message-text {
  position: relative;
  padding: 10px 14px;
  background-color: #fff;
  border-radius: 4px;
  word-break: break-all;
  line-height: 1.4;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}

.message-mine .message-text {
  background-color: #95ec69;
}

.message-status {
  position: absolute;
  top: -6px;
  left: -6px;
  font-size: 14px;
  z-index: 1;
}

.message-status .sending {
  color: #909399;
  animation: rotating 2s linear infinite;
}

.message-status .error {
  color: #f56c6c;
  font-size: 16px;
  cursor: pointer;
}

@keyframes rotating {
  from {
    transform: rotate(0);
  }
  to {
    transform: rotate(360deg);
  }
}

.message-input {
  padding: 20px;
  background-color: #fff;
  border-top: 1px solid #e6e6e6;
}

.input-actions {
  margin-top: 10px;
  display: flex;
  justify-content: flex-end;
}

.no-messages {
  text-align: center;
  color: #909399;
  padding: 20px;
}

.toolbar {
  padding: 8px 0;
  border-bottom: 1px solid #e6e6e6;
}

.tool-items {
  display: flex;
  gap: 8px;
}

.emoji-container {
  height: 350px;
  overflow-y: auto;
}

.emoji-container::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.emoji-container::-webkit-scrollbar-thumb {
  border-radius: 3px;
  background-color: #c0c4cc;
}

.emoji-container::-webkit-scrollbar-track {
  border-radius: 3px;
  background-color: #f5f7fa;
}

.emoji-list {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 12px;
  padding: 12px;
}

.emoji-item {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  cursor: pointer;
  border-radius: 4px;
  transition: background-color 0.2s;
  font-size: 20px;
}

.emoji-item:hover {
  background-color: #f0f2f5;
}

:global(.emoji-popover) {
  padding: 0;
}

.message-image {
  max-width: 200px;
  max-height: 200px;
  border-radius: 4px;
  cursor: pointer;
}

.image-error {
  width: 200px;
  height: 200px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background-color: #f5f7fa;
  color: #909399;
  font-size: 14px;
  border-radius: 4px;
}

.image-error .el-icon {
  font-size: 32px;
  margin-bottom: 8px;
}

.message-link {
  color: #409eff;
  text-decoration: none;
  word-break: break-all;
}

.message-link:hover {
  text-decoration: underline;
}
</style> 